#include "SelectWnd.h"
#include "ScreenshotUtil.h"
#include "CanvasContainerUI.h"

HBITMAP SelectWnd::sCurBitmap = nullptr;
SelectWnd *SelectWnd::instance = nullptr;

SelectWnd::SelectWnd()
    : m_bClipChoiced(false)
{
    m_ptClipBasePoint.x = m_ptClipBasePoint.y = 0;
    m_isSubOnBottom = true;
    ::ZeroMemory(&m_rcWindow, sizeof(m_rcWindow));
    ::ZeroMemory(&m_rcClipPadding, sizeof(m_rcClipPadding));
    ::ZeroMemory(m_sClipDrawStringBuf, sizeof(m_sClipDrawStringBuf));
}

SelectWnd::~SelectWnd()
{
}

void SelectWnd::StartCapture(OnSelectCallback cb)
{
    if (instance)
        delete instance;
    instance = new SelectWnd();
    instance->m_onSelectCallback = cb;
    instance->Create(NULL, _T(""), WS_VISIBLE | WS_POPUP, 0);
    // pScreenshotWnd->ShowModal();
    instance->ShowWindow(true);
    // delete pScreenshotWnd;
}

RECT SelectWnd::GetWindowRect() const
{
    return m_rcWindow;
}

RECT SelectWnd::GetClipPadding() const
{
    return m_rcClipPadding;
}

void SelectWnd::SetClipPadding(RECT rc)
{
    m_rcClipPadding = rc;
    _stprintf_s(m_sClipDrawStringBuf, MAX_PATH - 1, _T("file='desktopimagemask' scale9='%d,%d,%d,%d' hole='true'"),
                m_rcClipPadding.left, m_rcClipPadding.top, m_rcClipPadding.right, m_rcClipPadding.bottom);
    // m_pDesktopMask->SetBkImage(m_sClipDrawStringBuf);
    m_pDesktopMaskBorder->SetPos(GetClipRect());
    m_pDesktopCanvasContainer->SetPos(GetCanvasContainerRect());
    // 显示截屏窗口大小
    RefreshClipWinSize();
}
// 显示截屏窗口大小
void SelectWnd::RefreshClipWinSize()
{
    RECT canvasRc = GetCanvasContainerRect();
    RECT rcInset = m_pDesktopCanvasContainer->GetInset();
    canvasRc.left = canvasRc.left + rcInset.left;
    canvasRc.right = canvasRc.right - rcInset.right;
    canvasRc.top = canvasRc.top + rcInset.top;
    canvasRc.bottom = canvasRc.bottom - rcInset.bottom;

    wchar_t szSize[64] = {0};
    int itemWidth = canvasRc.right - canvasRc.left;
    int itemHeight = canvasRc.bottom - canvasRc.top;
    wsprintf(szSize, L"%dx%d", itemWidth, itemHeight);
    int txtWidth = 180;
    int txtHeight = 20;
    RECT txtRc = {canvasRc.left, canvasRc.top - txtHeight, canvasRc.left + txtWidth, canvasRc.top};
    // 上边缘 超出
    if (txtRc.top - m_rcWindow.top < txtHeight)
    {
        txtRc.top = canvasRc.top;
        txtRc.bottom = txtRc.top + txtHeight;
    }
}

void SelectWnd::ShowClipBorder()
{
    RECT rc{0, 0, 0, 0};
    HWND hWnd;
    ::EnableWindow(m_hWnd, FALSE);
    hWnd = SmallestWindowFromCursor(rc);
    m_selectedWnd = hWnd;
    ::EnableWindow(m_hWnd, TRUE);
    ::SetFocus(m_hWnd);
    rc.left = rc.left - m_rcWindow.left;
    if (rc.left < 0)
        rc.left = 0;
    rc.top = rc.top - m_rcWindow.top;
    if (rc.top < 0)
        rc.top = 0;
    rc.right = m_rcWindow.right - rc.right;
    if (rc.right < 0)
        rc.right = 0;
    rc.bottom = m_rcWindow.bottom - rc.bottom;
    if (rc.bottom < 0)
        rc.bottom = 0;
    // if (rc.left != m_rcClipPadding.left || rc.right != m_rcClipPadding.right || rc.top != m_rcClipPadding.top || rc.bottom != m_rcClipPadding.bottom)
    {
        SetClipPadding(rc);
        m_pDesktopMaskBorder->SetVisible(true);
        m_pDesktopCanvasContainer->SetVisible(false);
    }
    RefreshClipWinSize();
}

RECT SelectWnd::GetClipRect() const
{
    RECT rc = m_rcClipPadding;
    rc.left = rc.left + m_rcWindow.left;
    rc.top = rc.top + m_rcWindow.top;
    rc.right = m_rcWindow.right - rc.right;
    rc.bottom = m_rcWindow.bottom - rc.bottom;
    return rc;
}

RECT SelectWnd::GetCanvasContainerRect() const
{
    RECT rcInset = m_pDesktopCanvasContainer->GetInset();
    RECT rc = m_rcClipPadding;
    rc.left = rc.left + m_rcWindow.left - rcInset.left;
    rc.top = rc.top + m_rcWindow.top - rcInset.left;
    rc.right = m_rcWindow.right - rc.right + rcInset.left;
    rc.bottom = m_rcWindow.bottom - rc.bottom + rcInset.left;
    return rc;
}

CControlUI *SelectWnd::CreateControl(LPCTSTR pstrClass)
{
    if (lstrcmpi(pstrClass, _T("CanvasContainer")) == 0)
    {
        return new CCanvasContainerUI();
    }

    return NULL;
}
void SelectWnd::OnFinalMessage(HWND hWnd)
{
    __super::OnFinalMessage(hWnd);
    delete this;
    instance = nullptr;
}
DuiLib::CDuiString SelectWnd::GetSkinFile()
{
    return _T("select_wnd.xml");
}

LPCTSTR SelectWnd::GetWindowClassName() const
{
    return _T("select_wnd");
}

UINT SelectWnd::GetClassStyle() const
{
    return CS_DBLCLKS;
}

void SelectWnd::InitWindow()
{
    m_pm.SetDPI(CDPI::GetMainMonitorDPI());

    m_pDesktopImage = m_pm.FindControl(_T("desktopimage"));
    m_pDesktopMask = m_pm.FindControl(_T("desktopmask"));
    m_pDesktopMaskBorder = m_pm.FindControl(_T("desktopmaskborder"));
    m_pDesktopCanvasContainer = static_cast<CContainerUI *>(m_pm.FindControl(_T("desktopcanvascontainer")));

    ::GetWindowRect(::GetDesktopWindow(), &m_rcWindow);
    ::SetWindowPos(GetHWND(), NULL, m_rcWindow.left, m_rcWindow.top, m_rcWindow.right - m_rcWindow.left, m_rcWindow.bottom - m_rcWindow.top, SWP_NOZORDER);

    HBITMAP hDesktopBmp = CreateDesktopBitmap(GetHWND());
    m_pm.AddImage(_T("desktopimage"), hDesktopBmp, m_rcWindow.right - m_rcWindow.left, m_rcWindow.bottom - m_rcWindow.top, false);
    HBITMAP hDesktopBmpMask = CreateDesktopMaskBitmap(GetHWND());
    m_pm.AddImage(_T("desktopimagemask"), hDesktopBmpMask, m_rcWindow.right - m_rcWindow.left, m_rcWindow.bottom - m_rcWindow.top, true);
    HBITMAP hMagnifierBmp = CreateDesktopBitmap(GetHWND());
    m_pm.AddImage(_T("magnifierimage"), hMagnifierBmp, m_rcWindow.right - m_rcWindow.left, m_rcWindow.bottom - m_rcWindow.top, false);

    m_pDesktopImage->SetBkImage(_T("desktopimage"));
    m_pDesktopMask->SetBkImage(_T("desktopimagemask"));
    ShowClipBorder();
}
LRESULT SelectWnd::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
    if (uMsg == WM_LBUTTONDOWN)
    {
        if (!m_bClipChoiced)
        {
            m_pDesktopCanvasContainer->SetEnabled(false);
            m_ptClipBasePoint.x = GET_X_LPARAM(lParam);
            m_ptClipBasePoint.y = GET_Y_LPARAM(lParam);
            return 0;
        }
    }
    else if (uMsg == WM_LBUTTONUP)
    {
        if (!m_bClipChoiced)
        {
            m_bClipChoiced = true;
            // m_pMagnifierCtrl->SetVisible(false);
            m_pDesktopMaskBorder->SetVisible(false);
            m_pDesktopCanvasContainer->SetVisible(true);
            m_pDesktopCanvasContainer->SetEnabled(true);
            SetClipPadding(m_rcClipPadding);

            if (m_onSelectCallback)
                m_onSelectCallback(m_selectedWnd);
            Close();
            return 0;
        }
        else
        {
        }
    }
    else if (uMsg == WM_MOUSEMOVE)
    {
        if (!m_bClipChoiced)
        {
            if (::GetKeyState(VK_LBUTTON) < 0)
            { // 左键按下状态
                if (m_ptClipBasePoint.x != GET_X_LPARAM(lParam) || m_ptClipBasePoint.y != GET_Y_LPARAM(lParam))
                {
                    m_rcClipPadding.left = min(GET_X_LPARAM(lParam), m_ptClipBasePoint.x) - m_rcWindow.left;
                    if (m_rcClipPadding.left < 0)
                        m_rcClipPadding.left = 0;
                    m_rcClipPadding.top = min(GET_Y_LPARAM(lParam), m_ptClipBasePoint.y) - m_rcWindow.top;
                    if (m_rcClipPadding.top < 0)
                        m_rcClipPadding.top = 0;
                    m_rcClipPadding.right = m_rcWindow.right - max(GET_X_LPARAM(lParam), m_ptClipBasePoint.x);
                    if (m_rcClipPadding.right < 0)
                        m_rcClipPadding.right = 0;
                    m_rcClipPadding.bottom = m_rcWindow.bottom - max(GET_Y_LPARAM(lParam), m_ptClipBasePoint.y);
                    if (m_rcClipPadding.bottom < 0)
                        m_rcClipPadding.bottom = 0;
                    m_pDesktopMaskBorder->SetVisible(false);
                    m_pDesktopCanvasContainer->SetVisible(true);
                    SetClipPadding(m_rcClipPadding);
                }
            }
            else
            {
                ShowClipBorder();
            }
        }
        else
        {
        }
    }
    return 0;
}
void SelectWnd::Notify(TNotifyUI &msg)
{
    CDuiString name = msg.pSender->GetName();
    if (_tcsicmp(msg.sType, _T("click")) == 0)
    {
        OnClick(msg.pSender);
    }
}
void SelectWnd::OnClick(CControlUI *pSender)
{
    CDuiString strName = pSender->GetName().GetData();
}